package cn.com.infcn.monitor.filter;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.zip.GZIPOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.com.infcn.monitor.util.IFCMonitorUtils;
 
public class FileProcessor {
	private HttpServletRequest request;
	private HttpServletResponse response;
	
	public FileProcessor(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
	}
	public static String getExtension(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int i = filename.lastIndexOf('.');

            if ((i >-1) && (i < (filename.length() - 1))) {
                return filename.substring(i + 1);
            }
        }
        return "";
    } 
	private String getContentType(String file){
		String ext = getExtension(file).toLowerCase();
		if("jpg".equals(ext))ext = "jpeg";
		if("gif".equals(ext) || "png".equals(ext) || "jpeg".equals(ext)){
			return "image/"+ext;
		}
		if("html".equals(ext) || "css".equals(ext)){
			return "text/"+ext;
		}
		if("js".equals(ext)){
			return "application/javascript";
		}
		return "";
	}
	public void execute() throws IOException {
		execute(FileProcessor.class);
	}
	public void execute(Class<?> cls) throws IOException {
		// TODO Auto-generated method stub		
		String prefix=request.getContextPath()+"/";
		String str = request.getRequestURI().replaceFirst(prefix, "");	//   /usp/qde/script
		
		InputStream is = cls.getResourceAsStream(str);
		if(is==null){
			response.setStatus(404);
			response.setCharacterEncoding("utf-8");
			response.setContentType("text/html");
			PrintWriter writer = response.getWriter();
			writer.write("<h2>File not found</h2><hr>reported by IFCMonitor V" + MonitoringFilter.version + ", " +new Date());
			writer.flush();
			writer.close();
			return;
		}
		try{
			String md5 = "";
			String contentType = getContentType(str);
			try {
				MessageDigest messageDigest = MessageDigest.getInstance("MD5");
				messageDigest.update((MonitoringFilter.version+":"+str).getBytes());
				byte bytes[] = messageDigest.digest();
				StringBuffer hexString = new StringBuffer();
				for (int i=0;i<bytes.length;i++) {
					hexString.append(Integer.toHexString(0xFF & bytes[i]));
				}
				md5 = hexString.toString();
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				throw new IOException(e);
			}
			md5 = "\""+md5+"\"";
			
			response.addHeader("ETag",md5);
			SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz",Locale.ENGLISH);
			sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
			response.addHeader("Last-Modified",sdf.format(MonitoringFilter.START_DATE));
			
			String eTag = request.getHeader("If-None-Match");
			if(md5.equals(eTag)){
				response.setStatus(304);
				return;
			}
			
			if(!contentType.isEmpty()){
				response.setContentType(contentType);
				if(contentType.startsWith("text")){
					response.setCharacterEncoding("utf-8");
				}
			}
			OutputStream out = response.getOutputStream();
			String acceptEncoding = request.getHeader("Accept-Encoding");
			if(acceptEncoding!=null){
				acceptEncoding = acceptEncoding.toLowerCase();
				if(acceptEncoding.indexOf("gzip")>=0 && contentType.startsWith("text")){
					out = new GZIPOutputStream(response.getOutputStream());
					response.addHeader("Content-Encoding","gzip");
				}
			}
			byte[] buffer = new byte[512];
			while(true){
				int size = is.read(buffer);
				if(size<0)break;
				out.write(buffer,0,size);
			}
			out.flush();
			out.close();
		}finally{
			is.close();
		}
	}
}
